﻿// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 WINDOWSLIB_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何项目上不应定义此符号。这样，源文件中包含此文件的任何其他项目都会将
// WINDOWSLIB_API 函数视为是从 DLL 导入的，而此 DLL 则将用此宏定义的
// 符号视为是被导出的。


// 通过指定的互斥对象名 ，判断进程是否已经运行。
bool WINDOWSLIB_API IsProgressAlreadRun(const std::wstring& mutexName);

/*
**********************DLL延迟加载***********************************
* 工程属性-链接器-输入-延迟加载DLL，设置需要延迟加载的dll名字。
* 原理：
*	可执行程序先加载执行，所依赖的dll在正式调用时再加载进来。这样就可以把所需的dll
以资源形式插入程序中，程序正常执行后，把资源中的dll释放到本地，等正式调用dll时，就
可以正确加载释放的dll。	
**********************DLL延迟加载***********************************
*/

/*
**********************资源释放***********************************
把所需的资源插入程序：
1. 在解决方案/工程中选择“添加”->“资源”，选择“自定义”。
2. 在新建自定义资源时，设置资源类型，如：MyRes。
3. 选中新建的自定义资源“MyRes”，导入所需的文件。
释放资源：
1. 通过FindResource定位程序中的资源。主要通过“资源类型”和“资源名称”进行定位，
从而获取资源信息块的句柄。
2. 使用Sizeofresource获取资源的大小。
3. 通过LoadResource把资源加载到进程内存中。
4. 通过LockResource锁定加载到内存的资源，防止程序中其他操作影响这块内存；其中，
返回值就是资源在进程中的起始地址。
5. 根据资源大小以及进程内存起始地址，将资源数据读取出来并保存为本地文件。

以上原理就是通过PE文件结构，确定资源在PE文件中的偏移和大小。
**********************资源释放***********************************
*/

// 释放资源到本地
bool ReleaseResourcesLocally(UINT uiResourceName, TCHAR* lpszResourceType, TCHAR* lpszSaveFileName)
{
	// 获取指定模块里的资源
	HRSRC hRsrc = ::FindResource(NULL, MAKEINTRESOURCE(uiResourceName), lpszResourceType);
	if (hRsrc == NULL)
	{
		return FALSE;
	}

	// 获取资源大小
	DWORD dwSize = SizeofResource(NULL, hRsrc);
	if (dwSize <= 0)
	{
		return FALSE;
	}

	// 将资源加载到内存
	HGLOBAL hGlobal = ::LoadResource(NULL, hRsrc);
	if (hGlobal == NULL)
	{
		return FALSE;
	}

	// 锁定资源
	LPVOID lpVoid = ::LockResource(hGlobal);
	if (lpVoid == NULL)
	{
		return FALSE;
	}

	// 保存资源为本地文件
	FILE* fp = NULL;
	//fopen_s(&fp, lpszSaveFileName, "wb+");
	if (fp == NULL)
	{
		return FALSE;
	}

	fwrite(lpVoid, sizeof(TCHAR), dwSize, fp);
	fclose(fp);

	return TRUE;
}